import com.sun.xacml.TargetMatch;
import com.sun.xacml.attr.AttributeDesignator;
import com.sun.xacml.attr.AttributeValue;
import com.sun.xacml.cond.Function;
import com.sun.xacml.cond.FunctionFactory;

import java.io.BufferedReader;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;

/**
 * User: tej
 * Date: 25 févr. 2008
 * Time: 09:25:19
 */
@SuppressWarnings("unchecked")
public class OrBAC2XACMLUtils {

// ---------------------------------------------- Policy builder

    /**
     * Simple helper routine that creates a TargetMatch instance.
     *
     * @param type       the type of match
     * @param functionId the matching function identifier
     * @param designator the AttributeDesignator used in this match
     * @param value      the AttributeValue used in this match
     * @return the matching element
     */
    private static TargetMatch createTargetMatch(int type, String functionId,
                                                 AttributeDesignator designator,
                                                 AttributeValue value) {

        FunctionFactory factory;
        Function function = null;

        try {
            // get the factory that handles Target functions and get an
            // instance of the right function

            factory = FunctionFactory.getTargetInstance();
            function = factory.createFunction(functionId);


        } catch (Exception e) {
            e.printStackTrace();
        }

        return new TargetMatch(type, function, designator, value);
    }


    /**
     * Creates the Rule used in the Policy.
     *
     * @param ruleIdentifier the name give nt to the rule
     * @param status         whether a permission or a prohibition
     * @param role           the rule's role
     * @param activity       the activity to use
     * @param view           the view to use
     * @param context        the context to use
     * @return the rule XML string
     */
    private static String createRule(String ruleIdentifier, String status, String role, String activity, String view, String context) {

        String content;

        String effect = "Permit";
        // define the effect for the Rule

        if (status.equalsIgnoreCase("prohibition"))
            effect = "Deny";

        content = readFileContent("xacml_template/rule.xml");

        // replace the template content
        content = content.replace("$_RULE-ID_$", ruleIdentifier);
        content = content.replace("$_RULE-EFFECT_$", effect);
        content = content.replace("$_SUBJECT_$", role);
        content = content.replace("$_RESOURCE_$", view);
        content = content.replace("$_ACTION_$", activity);
        content = content.replace("$_CONTEXT_$", context);

        // System.out.println(content);
        return content;
    }


    private static String createPolicySet(String rules, String description) {

        String content;

        content = readFileContent("xacml_template/policySet.xml");

        // replace the template content
        content = content.replace("$_POLICY-NAME_$", "MyPolicy");
        content = content.replace("$_POLICY-DESCRIPTION_$", description);
        content = content.replace("$_RULES_$", rules);


        // System.out.println(content);
        return content;
    }


    public static String readFileContent(String fileName) {

        StringBuffer content;
        String thisLine;

        content = new StringBuffer("");

        try {
            BufferedReader br = new BufferedReader(new FileReader(fileName));
            while ((thisLine = br.readLine()) != null) {
               content.append(thisLine).append("\n");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        return content.toString();
    }

    /**
     * Produces an XACML file containing OrBAC rules contained in the array
     *
     * @param rules    hte list of rules in ruleName, status, rule, act, view, context
     * @param fileName the name of the file
     */
    public static void builtXACMLFile(String[][] rules, String fileName, String description) {

//------ generate the policy file
        StringBuffer rulesXACML = new StringBuffer("");
        String tmpRule;
        try {

            for (int i = 0; i < rules.length; i++) {


                tmpRule = createRule(rules[i][0].toUpperCase(), rules[i][1].toUpperCase(), rules[i][2].toUpperCase(),
                        rules[i][3].toUpperCase(), rules[i][4].toUpperCase(), rules[i][5].toUpperCase());

                rulesXACML.append(tmpRule);
            }

            // TODO check this: with or without any
            // default prohibition rule Is added at the end
            // Rule defaultRule = new Rule(new URI("FinalRule"), Result.DECISION_DENY,
            //        null, null, null);
            //rulesXACML.add(defaultRule);


            // create the policyset
            String xacmlPolicyContent = createPolicySet(rulesXACML.toString(), description);


            // writing to xml file
            FileOutputStream fos = new FileOutputStream(fileName);
            fos.write(xacmlPolicyContent.getBytes());
            fos.close();

        } catch (IOException e) {
            e.printStackTrace();

        }
    }


    public static void main(String[] args) {

        // System.out.println(readFileContent("xacml_template/policySet.xml"));

        System.out.println(readFileContent("xacml_template/policySet.xml"));


    }

}

